<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>基于小波变换的数字水印检测 | CC的部落格</title><meta name="author" content="CC康纳百川"><meta name="copyright" content="CC康纳百川"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><article data-clarity-region="article"></article><meta name="description" content="本篇文章简单介绍了使用Matlab做数字水印的嵌入与提取操作"><meta property="og:type" content="article"><meta property="og:title" content="基于小波变换的数字水印检测"><meta property="og:url" content="https://blog.ccknbc.cc/posts/digital-watermark-detection-based-on-wavelet-transform/"><meta property="og:site_name" content="CC的部落格"><meta property="og:description" content="本篇文章简单介绍了使用Matlab做数字水印的嵌入与提取操作"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/fea97888a40f0b051ab6f4b18057d37b_w2240_h1260_s3560.jpg"><meta property="article:published_time" content="2020-06-09T12:52:00.000Z"><meta property="article:modified_time" content="2020-06-09T13:00:00.000Z"><meta property="article:author" content="CC康纳百川"><meta property="article:tag" content="学习"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/fea97888a40f0b051ab6f4b18057d37b_w2240_h1260_s3560.jpg"><link rel="shortcut icon" href="/favicon.ico"><link rel="canonical" href="https://blog.ccknbc.cc/posts/digital-watermark-detection-based-on-wavelet-transform/"><link rel="preconnect" href="https://jsd.cdn.zzko.cn"><link rel="preconnect" href="//static.cloudflareinsights.com"><link rel="preconnect" href="//www.clarity.ms"><link rel="preconnect" href="//busuanzi.ibruce.info"><link rel="preconnect" href="https://97MUPN4DMC-dsn.algolia.net" crossorigin=""><meta name="google-site-verification" content="tUkgeN6Ih2ArWtjw47oNSSl4Af2_MWjiKLrzZptUCdM"><meta name="msvalidate.01" content="71ADBCC80D679CEA8080BAFDCD54E368"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.css" media="print" onload='this.media="all"'><script>(()=>{const t={set:(e,t,a)=>{var o;0!==a&&(o=Date.now(),localStorage.setItem(e,JSON.stringify({value:t,expiry:o+864e5*a})))},get:e=>{var t=localStorage.getItem(e);if(t){t=JSON.parse(t);if(!(Date.now()>t.expiry))return t.value;localStorage.removeItem(e)}}},a=(window.btf={saveToLocal:t,getScript:(o,n={})=>new Promise((t,e)=>{const a=document.createElement("script");a.src=o,a.async=!0,a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},Object.keys(n).forEach(e=>{a.setAttribute(e,n[e])}),document.head.appendChild(a)}),getCSS:(o,n=!1)=>new Promise((t,e)=>{const a=document.createElement("link");a.rel="stylesheet",a.href=o,n&&(a.id=n),a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),addGlobalFn:(e,t,a=!1,o=window)=>{var n=o.globalFn||{},d=n[e]||{};a&&d[a]||(d[a=a||Object.keys(d).length]=t,n[e]=d,o.globalFn=n)}},()=>{document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")}),o=()=>{document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","ffffff")};btf.activateDarkMode=a,btf.activateLightMode=o;var e=t.get("theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,d=window.matchMedia("(prefers-color-scheme: light)").matches,r=window.matchMedia("(prefers-color-scheme: no-preference)").matches,c=!n&&!d&&!r,n=(void 0===e?(d?o():n?a():(r||c)&&((d=(new Date).getHours())<=6||18<=d?a:o)(),window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{void 0===t.get("theme")&&(e.matches?a:o)()})):("light"===e?o:a)(),t.get("aside-status"));void 0!==n&&("hide"===n?document.documentElement.classList.add("hide-aside"):document.documentElement.classList.remove("hide-aside"));/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})()</script><script defer data-pjax="data-pjax" src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{&quot;token&quot;: &quot;35785b58f09f472ebfd7a2854973e6b8&quot;}"></script><script>!function(t,e,n,a,c,r){t[n]=t[n]||function(){(t[n].q=t[n].q||[]).push(arguments)},(c=e.createElement(a)).async=1,c.src="https://www.clarity.ms/tag/an4gdfm6a9",(r=e.getElementsByTagName(a)[0]).parentNode.insertBefore(c,r)}(window,document,"clarity","script")</script><script>const GLOBAL_CONFIG={postHeadAiDescription:{enable:!0,gptName:"CC",mode:"tianli",switchBtn:!0,btnLink:"https://tianli-blog.club/tianligpt/",randomNum:3,basicWordCount:1e3,key:"VCtoijR43E2uiVWkrZiC",Referer:"https://blog.ccknbc.cc/"},root:"/",algolia:void 0,localSearch:void 0,translate:{defaultEncoding:2,translateDelay:0,msgToTraditionalChinese:"繁",msgToSimplifiedChinese:"简"},noticeOutdate:{limitDay:15,position:"top",messagePrev:"本文最后一次更新为",messageNext:"天前，文章中的某些内容可能已过时！"},highlight:{plugin:"highlight.js",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:!1,highlightFullpage:!0,highlightMacStyle:!0},copy:{success:"复制成功",error:"复制错误",noSupport:"浏览器不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",dateSuffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:{limitCount:100,languages:{author:"作者: CC康纳百川",link:"链接: ",source:"来源: CC的部落格",info:"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},lightbox:"fancybox",Snackbar:{chs_to_cht:"你已切换为繁体中文",cht_to_chs:"你已切换为简体中文",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"#49b1f5",bgDark:"#1f1f1f",position:"top-center"},infinitegrid:{js:"https://jsd.cdn.zzko.cn/npm/@egjs/infinitegrid/dist/infinitegrid.min.js",buttonText:"加载更多"},isPhotoFigcaption:!1,islazyload:!0,isAnchor:!1,percent:{toc:!0,rightside:!0},autoDarkmode:!0}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={postAI:"本篇文章简单介绍了使用Matlab做数字水印的嵌入与提取操作",pageFillDescription:"基于小波变换的数字水印检测数字水印技术原理数字水印技术实际上就是通过对水印载体的分析水印信息的处理水印嵌入点的选择嵌入方式的设计嵌入调制的控制和提取检测方法等相关技术环节进行合理优化寻求满足不可感知性鲁棒性和安全性等约束条件下的准最优化设计问题在实际应用中一个完整水印系统的设计通常包括水印的生成嵌入检测和提取四个部分水印生成通常基于伪随机数发生器或混沌系统来产生水印信号从水印的鲁棒性和安全性方面来考虑常常需要对原水印进行预处理来适应水印嵌入贺认水印嵌入在尽量保证水印不可感知性的前提下嵌入最大强度的水印可提高水印的稳健性常用的水印嵌入准则有加法准则乘法准则和融合准则水印检测指判断水印载体中是否存在水印的过程水印提取指水印被比较精确地提取的过程水印的提取和检测可以需要原始图像的参与明检测也可不需要原始图像的参与盲检测数字水印的分类按水印的特性鲁棒数字水印要求嵌入的水印能够经受各种常用的编辑处理脆弱数字水印需要对信号的改动足够敏感是人们能够根据脆弱水印的状态判断出数据是否被篡改按水印的检测过程明文水印检测工程中需要原始数据普遍来讲鲁棒性较之盲水印要好盲水印只需要密钥不需要原始数据按水印的内容有意义水印水印是商标音频片段等无意义水印序列号仅检测是否含水印按水印的隐藏位置空域频域时域数字水印技术基本上具有下面几个方面的特点安全性数字水印的信息应是安全的难以篡改或伪造同时应当有较低的误检测率当原内容发生变化时数字水印应当发生变化从而可以检测原始数据的变更当然数字水印同样对重复添加有很强的抵抗性隐蔽性数字水印应是不可知觉的而且应不影响被保护数据的正常使用不会降质鲁棒性是指在经历多种无意或有意的信号处理过程后数字水印仍能保持部分完整性并能被准确鉴别可能的信号处理过程包括信道噪声滤波数模与模数转换重采样剪切位移尺度变化以及有损压缩编码等嵌入容量是指载体在不发生形变的前提下可嵌入的水印信息量尤其是隐蔽通信领域的特殊性对水印的容量需求很大图数字水印嵌入与提取框图典型的数字水印算法数字水印的技术实现空域方法是最简单的嵌入水印的方法事实上任何一幅图片都具备一定的容噪性这表现在像素数据的最低有效位对人眼的视觉影响很小秘密信息就隐藏在图像每一个像素的最低位或次低位实现其不可见性频域将图片的灰度强弱视为图片的频域通过某种变换手段傅里叶变换离散余弦变换小波变换等将图像变换到频域小波域在频域对图像添加水印再通过逆变换将图像转换为空间域相对于空域手段频域手段隐匿性更强抗攻击性更高以的像素为单位进行生成的是的系数数据块变换的最大特点是对于一般的图像都能够将像块的能量集中于少数低频系数上即生成系数块中仅左上角的少量低频系数数值较大其余系数的数值很小这样就可能只编码和传输少数系数而不严重影响图像质量小波变换小波就是小区域长度有限均值为的波形小波变换就是选择适当的基本小波或母小波通过对基本小波的平移伸缩而形成一系列的小波这簇小波作为基可以构成一系列嵌套的信号子空间然后将欲分析的信号例如图像投影到各个大小不同的信号子空间之中以观察相应的特性这样就相当于我们用不同的焦距去观察一个物体可从宏观到微观从概貌到细节观察得十分详尽所以小波变换又被称为数学显微镜空域频域该算法通过混沌置乱水印图像建立水印与载体数据之间的单向映射函数使用两种不同的嵌入方法先后嵌入水印到空域和域水印被多次嵌入实现了水印的盲提取数字水印的应用场景多媒体作品盗版追溯利用数字水印的不可见性在不影响作品的情况下加入版权信息的数字水印可抗击拷贝剪切证件的防伪认证如学历证合同票据等携带数字水印后可通过制定的方式提取水印验证证件等数字文件是否被涂改阿里事件阿里追查泄密员工的时间本身说明水印可以有效的追溯信息的释放源隐蔽信息传递水印可携带加密信息后藏在多媒体文件中传播并通过特定的提取方式获取水印可以作为一种隐蔽信息的通信方式源程序代码及部分注释基础设置模块同时存储着密钥全局变量秘钥置乱次数秘钥随机数种子是否显示图像不显示显示嵌入水印模块基于小波变换数字水印嵌入载体图像灰度图水印图像二值图且长宽相等秘钥置乱次数置乱要求水印图像长宽必须相等载体小波分解一级小波分解二级小波分解水印置乱与嵌入原始水印置乱水印变换次数数字水印嵌入原始图像添加水印提取水印模块置乱要求水印图像长宽必须相等数字水印提取结果原始水印提取水印调用模块移动窗口到屏幕中心请选择底图文件打开图像读取原始图像请选择水印文件选择完毕您可点击查看以确认是否需要重新选择提示转换为灰度图读取水印图像转化成二值图像水印的行数水印的列数将图像扩展为长宽相等载体图像与水印图像载体图像水印图像基于小波的水印技术运行结果演示图像的选择与导入进入主界面图主界面点击选择图片分别选择载体图像和水印图像图选择底图文件图选择水印文件两项都选择完毕后提示选择完成图选择完毕帮助提示框对于取消选择未设置警告与报错提示防止过多弹窗载体图像小波变换这部分未单独新开按钮和图片显示窗口但程序的确执行了用户无需知晓水印图像的预处理图预处理成二值图像后的水印小波数字水印的嵌入图原始水印和置乱水印以及原始图像和添加水印之后的图像对比小波数字水印的提取图原始水印和提取的水印的对比将原始水印和提取水印进行对比两个相关系数为相关系数越接近则提取的水印和原始水印越相似",title:"基于小波变换的数字水印检测",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!1,postUpdate:"2020-06-09 21:00:00"}</script><script>"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(r=>{r.onupdatefound=()=>{const e=r.installing;e.onstatechange=()=>{"installed"===e.state&&(navigator.serviceWorker.controller?(void 0!==GLOBAL_CONFIG.Snackbar&&btf.snackbarShow("已刷新缓存，更新为最新内容"),navigator.serviceWorker.controller.postMessage({type:"skipWaiting"})):console.log("第一次注册Service Worker"))}}}),navigator.serviceWorker.addEventListener("message",e=>{e.data&&"refresh"===e.data.type&&(console.log("收到刷新页面请求，开始刷新页面"),window.location.reload())}))</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/assets/font-awesome-animation.min.css" media="defer" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/tag_plugins.css" media="defer" onload='this.media="all"'><meta name="generator" content="Hexo 7.2.0"><link rel="alternate" href="/atom.xml" title="CC的部落格" type="application/atom+xml"><link rel="alternate" href="/rss.xml" title="CC的部落格" type="application/rss+xml"></head><body><script>window.paceOptions={restartOnPushState:!1},btf.addGlobalFn("pjaxSend",()=>{Pace.restart()},"pace_restart")</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/gh/CodeByZach/pace/themes/green/pace-theme-flash.css"><script src="https://jsd.cdn.zzko.cn/npm/pace-js/pace.min.js"></script><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/logo.png" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/404.jpg"' alt="avatar"></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">38</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">7</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr class="custom-hr"><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/fea97888a40f0b051ab6f4b18057d37b_w2240_h1260_s3560.jpg)"><nav id="nav"><span id="blog-info"><a href="/" title="CC的部落格"><span class="site-name">CC的部落格</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></span></div><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="post-info"><h1 class="post-title">基于小波变换的数字水印检测</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-06-09T12:52:00.000Z" title="发表于 2020-06-09 20:52:00">2020-06-09</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-06-09T13:00:00.000Z" title="更新于 2020-06-09 21:00:00">2020-06-09</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%AD%A6%E4%B9%A0/">学习</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">3k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>11分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" data-flag-title="基于小波变换的数字水印检测"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout hide-aside" id="content-inner"><div id="post"><div class="post-ai-description"><div class="ai-title"><i class="fa-solid fa-newspaper"></i><div class="ai-title-text">AI-摘要</div><div id="ai-Toggle" title="CC/Tianli 模式切换">切换</div><i class="fa-solid fa-podcast" title="Tianli 模式下朗读摘要"></i><i class="fa-solid fa-arrow-rotate-right" title="Tianli 模式下刷新摘要"></i><div id="ai-tag">Tianli GPT</div></div><div class="ai-explanation">AI初始化中...</div><div class="ai-btn-box"><div class="ai-btn-item">介绍自己 🙈</div><div class="ai-btn-item">生成摘要 👋</div><div class="ai-btn-item">相关推荐 📖</div><div class="ai-btn-item">前往主页 🏠</div><div class="ai-btn-item" id="go-tianli-blog">前往爱发电购买</div></div><script data-pjax src="/"></script></div><article class="post-content" id="article-container"><p><a href="https://blog.ccknbc.cc/posts/digital-watermark-detection-based-on-wavelet-transform/">基于小波变换的数字水印检测</a> <strong>数字水印技术原理</strong></p><p>数字水印技术实际上就是通过对水印载体的分析、水印信息的处理、水印嵌入点的选择、嵌入方式的设计、嵌入调制的控制和提取检测方法等相关技术环节进行合理优化，寻求满足不可感知性、鲁棒性和安全性等约束条件下的准最优化设计问题。在实际应用中，一个完整水印系统的设计通常包括水印的生成、嵌入、检测和提取四个部分。</p><p><strong>1   水印生成</strong></p><p>通常基于伪随机数发生器或混沌系统来产生水印信号，从水印的鲁棒性和安全性方面来考虑，常常需要对原水印进行预处理来适应水印嵌入贺认。</p><p><strong>2</strong> <strong>水印嵌入</strong></p><p>在尽量保证水印不可感知性的前提下，嵌入最大强度的水印，可提高水印的稳健性。常用的水印嵌入准则有加法准则、乘法准则和融合准则。</p><p><strong>3 水印检测</strong></p><p>指判断水印载体中是否存在水印的过程。</p><p><strong>4 水印提取</strong></p><p>指水印被比较精确地提取的过程。 水印的提取和检测可以需要原始图像的参与（明检测）， 也可不需要原始图像的参与（盲检测）</p><p><strong>数字水印的分类</strong></p><ul><li>按水印的特性</li><li>鲁棒数字水印：要求嵌入的水印能够经受各种常用的编辑处理</li><li>脆弱数字水印：需要对信号的改动足够敏感，是人们能够根据脆弱水印的状态判断出数据是否被篡改。</li><li>按水印的检测过程</li><li>明文水印：检测工程中，需要原始数据。普遍来讲，鲁棒性较之盲水印要好。</li><li>盲水印：只需要密钥，不需要原始数据</li><li>按水印的内容</li><li>有意义水印：水印是商标、音频片段等</li><li>无意义水印：序列号，仅检测是否含水印</li><li>按水印的隐藏位置</li><li>空域</li><li>频域</li><li>时域</li></ul><p>数字水印技术基本上具有下面几个方面的特点：</p><p>----<strong>安全性</strong>：数字水印的信息应是安全的，难以篡改或伪造，同时，应当有较低的误检测率，当原内容发生变化时，数字水印应当发生变化，从而可以检测原始数据的变更；当然数字水印同样对重复添加有很强的抵抗性</p><p>----<strong>隐蔽性</strong>：数字水印应是不可知觉的，而且应不影响被保护数据的正常使用；不会降质；</p><p>----<strong>鲁棒性</strong>：是指在经历多种无意或有意的信号处理过程后，数字水印仍能保持部分完整性并能被准确鉴别。可能的信号处理过程包括信道噪声、滤波、数/模与模/数转换、重采样、剪切、位移、尺度变化以及有损压缩编码等。</p><p>–<strong>嵌入容量</strong>(embedding capacity)：是指载体在不发生形变的前提下可嵌入的水印信息量。尤其是隐蔽通信领域的特殊性，对水印的容量需求很大。</p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfsmLi.gif#height=339&amp;id=Br1jy&amp;originHeight=339&amp;originWidth=266&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=266" alt="" loading="lazy"></p><p><strong>图 1 数字水印嵌入与提取框图</strong></p><p><strong>典型的数字水印算法</strong></p><p><strong>数字水印的技术实现</strong></p><p><strong>空域-LSB</strong></p><p>LSB 方法是最简单的嵌入水印的方法。事实上 ，任何一幅 图片都具备一定的容噪性 ，这表现在像素数据的最低有效位(Least Significant Bit，LSB)对 人 眼的视觉影响很 小，秘密信息就隐藏在图像每一个像素的最低位或次低位 ，实现其不 可见性。</p><p><strong>频域</strong></p><p>将图片的灰度强弱，视为图片的频域。通过某种变换手段（傅里叶变换，离散余弦变换，小波变换等）将图像变换到频域（小波域），在频域对图像添加水印，再通过逆变换，将图像转换为空间域。相对于空域手段，频域手段隐匿性更强，抗攻击性更高。</p><p><strong>DCT</strong></p><p>DCT 以 8x8 的像素为单位进行，生成的是 8x8 的 DCT 系数数据块。DCT 变换的最大特点是对于一般的图像都能够将像块的能量集中于少数低频 DCT 系数上，即生成 8x8DCT 系数块中，仅左上角的少量低频系数数值较大，其余系数的数值很小，这样就可能只编码和传输少数系数而不严重影响图像质量。</p><p><strong>小波变换</strong></p><p>“小波”就是小区域、长度有限、均值为 0 的波形。小波变换就是选择适当的基本小波或母小波 ψ(t)，通过对基本小波的平移、伸缩而形成一系列的小波，这簇小波作为基可以构成一系列嵌套的（信号）子空间，然后将欲分析的信号（例如图像）投影到各个大小不同的（信号）子空间之中，以观察相应的特性。这样，就相当于我们用不同的焦距去观察一个物体，可从宏观到微观，从概貌到细节观察得十分详尽。所以小波变换又被称为“数学显微镜”。</p><p><strong>空域+频域</strong></p><p>该算法通过混沌置乱水印图像，建立水印与载体数据之间的 Hash 单向映射函数，使用两种不同的嵌入方法，先后嵌入水印到空域和 DFT 域。水印被多次嵌入，实现了水印的盲提取。</p><p><strong>数字水印的应用场景</strong></p><ul><li>多媒体作品盗版追溯：利用数字水印的不可见性，在不影响作品的情况下，加入版权信息的数字水印，可抗击拷贝，剪切。</li><li>证件的防伪认证：如学历证，合同，票据等，携带数字水印后，可通过制定的方式提取水印，验证证件等数字文件是否被涂改；</li><li>阿里事件：阿里追查泄密员工的时间本身，说明，水印可以有效的追溯信息的释放源；</li><li>隐蔽信息传递：水印可携带加密信息后，藏在多媒体文件中传播，并通过特定的提取方式获取水印。可以作为一种隐蔽信息的通信方式。</li></ul><p><strong>源程序代码及部分注释</strong></p><p><strong>基础设置模块，同时存储着密钥，全局变量 main.m</strong></p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">global</span> I ;</span><br><span class="line"><span class="keyword">global</span> W;</span><br><span class="line"><span class="keyword">global</span> P;</span><br><span class="line"><span class="keyword">global</span> Iw;</span><br><span class="line">ntimes=<span class="number">23</span>; <span class="comment">% 秘钥1,Arnold置乱次数</span></span><br><span class="line">rngseed=<span class="number">59433</span>; <span class="comment">% 秘钥2，随机数种子</span></span><br><span class="line">flag=<span class="number">1</span>; <span class="comment">%是否显示图像，0 不显示，1 显示</span></span><br></pre></td></tr></table></figure><p><strong>嵌入水印模块：setdwtwatermark.m</strong></p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line">matlabfunction [Iw,psnr]=setdwtwatermark(I,W,ntimes,rngseed,flag)</span><br><span class="line"><span class="comment">%基于小波变换数字水印嵌入</span></span><br><span class="line"><span class="comment">%I：载体图像，灰度图</span></span><br><span class="line"><span class="comment">%W：水印图像，二值图，且长宽相等</span></span><br><span class="line"><span class="comment">%ntimes: 秘钥1,Arnold置乱次数</span></span><br><span class="line">I=imcrop(I,[<span class="number">0</span> <span class="number">0</span> <span class="built_in">size</span>(I,<span class="number">2</span>) <span class="built_in">size</span>(I,<span class="number">1</span>)<span class="number">-1</span>]);</span><br><span class="line"><span class="built_in">type</span>=class(I);</span><br><span class="line">I=double(I);</span><br><span class="line">W=logical(W);</span><br><span class="line">[mI,nI]=<span class="built_in">size</span>(I);</span><br><span class="line">[mW,nW]=<span class="built_in">size</span>(W);</span><br><span class="line"><span class="keyword">if</span> mW~=nW</span><br><span class="line">  error(<span class="string">&#x27;SETDWTWATERMARK:ARNOLD&#x27;</span>,<span class="string">&#x27;ARNOLD置乱要求水印图像长宽必须相等！&#x27;</span>)</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">[ca1,ch1,cv1,cd1]=dwt2(I,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line">[ca2,ch2,cv2,cd2]=dwt2(ca1,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line"><span class="keyword">if</span> flag</span><br><span class="line">  <span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>,<span class="string">&#x27;载体小波分解&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">121</span>)</span><br><span class="line">  imagesc([wcodemat(ca1),wcodemat(ch1);wcodemat(cv1),wcodemat(cd1)])</span><br><span class="line">  title(<span class="string">&#x27;一级小波分解&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">122</span>)</span><br><span class="line">  imagesc([wcodemat(ca2),wcodemat(ch2);wcodemat(cv2),wcodemat(cd2)])</span><br><span class="line">  title(<span class="string">&#x27;二级小波分解&#x27;</span>)</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">Wa=W;</span><br><span class="line">H=[<span class="number">1</span>,<span class="number">1</span>;<span class="number">1</span>,<span class="number">2</span>]^ntimes;</span><br><span class="line"><span class="keyword">for</span> <span class="built_in">i</span>=<span class="number">1</span>:nW</span><br><span class="line">  <span class="keyword">for</span> <span class="built_in">j</span>=<span class="number">1</span>:nW</span><br><span class="line">    idx=<span class="built_in">mod</span>(H*[<span class="built_in">i</span><span class="number">-1</span>;<span class="built_in">j</span><span class="number">-1</span>],nW)+<span class="number">1</span>;</span><br><span class="line">    Wa(idx(<span class="number">1</span>),idx(<span class="number">2</span>))=W(<span class="built_in">i</span>,<span class="built_in">j</span>);</span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">flag=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span> flag</span><br><span class="line">  <span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>,<span class="string">&#x27;水印置乱与嵌入&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">221</span>)</span><br><span class="line">  imshow(W)</span><br><span class="line">  title(<span class="string">&#x27;原始水印&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">222</span>)</span><br><span class="line">  imshow(Wa)</span><br><span class="line">  title([<span class="string">&#x27;置乱水印，变换次数=&#x27;</span>,num2str(ntimes)]);</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="comment">%数字水印嵌入</span></span><br><span class="line">ca2w=ca2;</span><br><span class="line">rng(rngseed);</span><br><span class="line">idx=randperm(<span class="built_in">numel</span>(ca2),<span class="built_in">numel</span>(Wa));</span><br><span class="line"><span class="keyword">for</span> <span class="built_in">i</span>=<span class="number">1</span>:<span class="built_in">numel</span>(Wa)</span><br><span class="line">  c=ca2(idx(<span class="built_in">i</span>));</span><br><span class="line">  z=<span class="built_in">mod</span>(c,nW);</span><br><span class="line">  <span class="keyword">if</span> Wa(<span class="built_in">i</span>)</span><br><span class="line">    <span class="keyword">if</span> z&lt;nW/<span class="number">4</span></span><br><span class="line">      f=c-nW/<span class="number">4</span>-z;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">      f=c+nW*<span class="number">3</span>/<span class="number">4</span>-z;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">    <span class="keyword">if</span> z&lt;nW*<span class="number">3</span>/<span class="number">4</span></span><br><span class="line">      f=c+nW/<span class="number">4</span>-z;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">      f=c+nW*<span class="number">5</span>/<span class="number">4</span>-z;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line">  ca2w(idx(<span class="built_in">i</span>))=f;</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">ca1w=idwt2(ca2w,ch2,cv2,cd2,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line">Iw=idwt2(ca1w,ch1,cv1,cd1,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line">Iw=Iw(<span class="number">1</span>:mI,<span class="number">1</span>:nI);</span><br><span class="line">mn=<span class="built_in">numel</span>(I);</span><br><span class="line">Imax=<span class="built_in">max</span>(I(:));</span><br><span class="line">psnr=<span class="number">10</span>*<span class="built_in">log10</span>(mn*Imax^<span class="number">2</span>/sum((I(:)-Iw(:)).^<span class="number">2</span>));</span><br><span class="line">I=cast(I,<span class="built_in">type</span>);</span><br><span class="line">Iw=cast(Iw,<span class="built_in">type</span>);</span><br><span class="line"><span class="keyword">if</span> flag</span><br><span class="line">  subplot(<span class="number">223</span>)</span><br><span class="line">  imshow(I);</span><br><span class="line">  title(<span class="string">&#x27;原始图像&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">224</span>);</span><br><span class="line">  imshow(Iw);</span><br><span class="line">  title([<span class="string">&#x27;添加水印，PSNR=&#x27;</span>,num2str(psnr)]);</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><p><strong>提取水印模块：getdwtwatermark.m</strong></p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="params">[Wg,nc]</span>=<span class="title">getdwtwatermark</span><span class="params">(Iw,W,P,ntimes,rngseed,flag)</span></span></span><br><span class="line">[mW,nW]=<span class="built_in">size</span>(W);</span><br><span class="line"><span class="keyword">if</span> mW~=nW</span><br><span class="line">  error(<span class="string">&#x27;GETDWTWATERMARK:ARNOLD&#x27;</span>,<span class="string">&#x27;ARNOLD置乱要求水印图像长宽必须相等！&#x27;</span>)</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">Iw=double(Iw);</span><br><span class="line">W=logical(W);</span><br><span class="line">ca1w=dwt2(Iw,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line">ca2w=dwt2(ca1w,<span class="string">&#x27;haar&#x27;</span>);</span><br><span class="line">Wa=W;</span><br><span class="line">rng(rngseed);</span><br><span class="line">idx=randperm(<span class="built_in">numel</span>(ca2w),<span class="built_in">numel</span>(Wa));</span><br><span class="line"><span class="keyword">for</span> <span class="built_in">i</span>=<span class="number">1</span>:<span class="built_in">numel</span>(Wa)</span><br><span class="line">  c=ca2w(idx(<span class="built_in">i</span>));</span><br><span class="line">  z=<span class="built_in">mod</span>(c,nW);</span><br><span class="line">  <span class="keyword">if</span> z&lt;nW/<span class="number">2</span></span><br><span class="line">    Wa(<span class="built_in">i</span>)=<span class="number">0</span>;</span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">    Wa(<span class="built_in">i</span>)=<span class="number">1</span>;</span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">Wg=Wa;</span><br><span class="line">H=[<span class="number">2</span> <span class="number">-1</span>;<span class="number">-1</span>,<span class="number">1</span>]^ntimes;</span><br><span class="line"><span class="keyword">for</span> <span class="built_in">i</span>=<span class="number">1</span>:nW</span><br><span class="line">  <span class="keyword">for</span> <span class="built_in">j</span>=<span class="number">1</span>:nW</span><br><span class="line">    idx=<span class="built_in">mod</span>(H*[<span class="built_in">i</span><span class="number">-1</span>;<span class="built_in">j</span><span class="number">-1</span>],nW)+<span class="number">1</span>;</span><br><span class="line">    Wg(idx(<span class="number">1</span>),idx(<span class="number">2</span>))=Wa(<span class="built_in">i</span>,<span class="built_in">j</span>);</span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">nc=sum(Wg(:).*W(:))/<span class="built_in">sqrt</span>(sum(Wg(:).^<span class="number">2</span>))/<span class="built_in">sqrt</span>(sum(W(:).^<span class="number">2</span>));</span><br><span class="line">flag=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span> flag</span><br><span class="line">  <span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>,<span class="string">&#x27;数字水印提取结果&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">121</span>)</span><br><span class="line">  W=imcrop(W,[<span class="number">0</span> <span class="number">0</span> <span class="built_in">size</span>(P,<span class="number">2</span>) <span class="built_in">size</span>(P,<span class="number">1</span>)]);</span><br><span class="line"> imshow(W)</span><br><span class="line">  title(<span class="string">&#x27;原始水印&#x27;</span>)</span><br><span class="line">  subplot(<span class="number">122</span>)</span><br><span class="line">  Wg=imcrop(Wg,[<span class="number">0</span> <span class="number">0</span> <span class="number">122</span> <span class="number">107</span>]);</span><br><span class="line">  imshow(Wg)</span><br><span class="line">  title([<span class="string">&#x27;提取水印，NC=&#x27;</span>,num2str(nc)]);</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><p><strong>GUI 调用模块 watermatk.m</strong></p><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">varargout</span> = <span class="title">watermark</span><span class="params">(varargin)</span></span></span><br><span class="line">gui_Singleton = <span class="number">1</span>;</span><br><span class="line">gui_State = struct(<span class="string">&#x27;gui_Name&#x27;</span>,    mfilename, ...</span><br><span class="line">          <span class="string">&#x27;gui_Singleton&#x27;</span>, gui_Singleton, ...</span><br><span class="line">          <span class="string">&#x27;gui_OpeningFcn&#x27;</span>, @watermark_OpeningFcn, ...</span><br><span class="line">          <span class="string">&#x27;gui_OutputFcn&#x27;</span>, @watermark_OutputFcn, ...</span><br><span class="line">          <span class="string">&#x27;gui_LayoutFcn&#x27;</span>, [] , ...</span><br><span class="line">          <span class="string">&#x27;gui_Callback&#x27;</span>,  []);</span><br><span class="line"><span class="keyword">if</span> nargin &amp;&amp; ischar(varargin&#123;<span class="number">1</span>&#125;)</span><br><span class="line">  gui_State.gui_Callback = str2func(varargin&#123;<span class="number">1</span>&#125;);</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="keyword">if</span> nargout</span><br><span class="line">  [varargout&#123;<span class="number">1</span>:nargout&#125;] = gui_mainfcn(gui_State, varargin&#123;:&#125;);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  gui_mainfcn(gui_State, varargin&#123;:&#125;);</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">watermark_OpeningFcn</span><span class="params">(hObject, eventdata, handles, varargin)</span></span></span><br><span class="line">movegui( hObject,<span class="string">&#x27;center&#x27;</span> );</span><br><span class="line">handles.output = hObject;<span class="comment">%移动窗口到屏幕中心</span></span><br><span class="line">guidata(hObject, handles);</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">varargout</span> = <span class="title">watermark_OutputFcn</span><span class="params">(hObject, eventdata, handles)</span></span></span><br><span class="line">varargout&#123;<span class="number">1</span>&#125; = handles.output</span><br><span class="line"><span class="comment">% --- Executes on button press in pushbutton1.</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">pushbutton1_Callback</span><span class="params">(hObject, eventdata, handles)</span></span></span><br><span class="line">main</span><br><span class="line">[filename pathname]=uigetfile(&#123;<span class="string">&#x27;*.jpg;*.bmp&#x27;</span>;<span class="string">&#x27;*.*&#x27;</span>&#125;,<span class="string">&#x27;请选择底图文件&#x27;</span>);</span><br><span class="line"><span class="comment">%%打开图像</span></span><br><span class="line">I=imread(filename); <span class="comment">%读取原始图像</span></span><br><span class="line">[filename pathname]=uigetfile(&#123;<span class="string">&#x27;*.png;*.tif&#x27;</span>;<span class="string">&#x27;*.*&#x27;</span>&#125;,<span class="string">&#x27;请选择水印文件&#x27;</span>);</span><br><span class="line">helpdlg(<span class="string">&#x27;选择完毕，您可点击查看以确认是否需要重新选择&#x27;</span>,<span class="string">&#x27;提示&#x27;</span>);</span><br><span class="line">I = rgb2gray(I);<span class="comment">%转换为灰度图</span></span><br><span class="line">W = imread(filename);<span class="comment">%读取水印图像</span></span><br><span class="line"><span class="keyword">if</span> strcmp(filename(<span class="keyword">end</span><span class="number">-3</span>:<span class="keyword">end</span>),<span class="string">&#x27;tif&#x27;</span>)</span><br><span class="line">  W= rgb2gray(W);</span><br><span class="line">  W=imbinarize(W);<span class="comment">%转化成二值图像</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line">P=W;</span><br><span class="line">Mm=<span class="built_in">size</span>(W,<span class="number">1</span>); <span class="comment">%水印的行数</span></span><br><span class="line">Nm=<span class="built_in">size</span>(W,<span class="number">2</span>); <span class="comment">%水印的列数</span></span><br><span class="line"><span class="comment">%将图像扩展为长宽相等</span></span><br><span class="line"><span class="keyword">if</span> Mm&lt;Nm</span><br><span class="line">  Max=Nm;</span><br><span class="line">  Min=Mm;</span><br><span class="line">  <span class="keyword">for</span> <span class="built_in">i</span>=Min:Max</span><br><span class="line">    <span class="keyword">for</span> <span class="built_in">j</span>=<span class="number">1</span>:Max</span><br><span class="line">      W(<span class="built_in">i</span>,<span class="built_in">j</span>)=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  Max=Mm;</span><br><span class="line">  Min=Nm;</span><br><span class="line">  <span class="keyword">for</span> <span class="built_in">i</span>=<span class="number">1</span>:Max</span><br><span class="line">    <span class="keyword">for</span> <span class="built_in">j</span>=Min:Max</span><br><span class="line">      W(<span class="built_in">i</span>,<span class="built_in">j</span>)=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">  <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">pushbutton2_Callback</span><span class="params">(hObject, eventdata, handles)</span></span></span><br><span class="line">main</span><br><span class="line"><span class="built_in">figure</span>(<span class="string">&#x27;Name&#x27;</span>,<span class="string">&#x27;载体图像与水印图像&#x27;</span>)</span><br><span class="line">subplot(<span class="number">211</span>);</span><br><span class="line">imshow(I);</span><br><span class="line">title(<span class="string">&#x27;载体图像&#x27;</span>)</span><br><span class="line">subplot(<span class="number">212</span>);</span><br><span class="line">imshow(P);</span><br><span class="line">title(<span class="string">&#x27;水印图像&#x27;</span>)</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">pushbutton3_Callback</span><span class="params">(hObject, eventdata, handles)</span></span></span><br><span class="line">main</span><br><span class="line">[Iw,psnr]=setdwtwatermark(I,W,ntimes,rngseed,<span class="number">0</span>);</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">pushbutton4_Callback</span><span class="params">(hObject, eventdata, handles)</span></span></span><br><span class="line">main</span><br><span class="line">[Wg,nc]=getdwtwatermark(Iw,W,P,ntimes,rngseed,<span class="number">0</span>);</span><br></pre></td></tr></table></figure><p><strong>基于小波的水印技术 运行结果演示</strong></p><p><strong>1 图像的选择与导入</strong></p><p>进入 GUI 主界面</p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfsGAW.png#height=728&amp;id=z3lLB&amp;originHeight=728&amp;originWidth=460&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=460" alt="" loading="lazy"></p><p><strong>图 2 GUI 主界面</strong></p><p>点击选择图片，分别选择载体图像和水印图像</p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfs4wL.png#height=591&amp;id=ulHM2&amp;originHeight=591&amp;originWidth=943&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=943" alt="" loading="lazy"></p><p><strong>图 3 选择底图文件</strong></p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfsHFw.png#height=591&amp;id=DloEr&amp;originHeight=591&amp;originWidth=943&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=943" alt="" loading="lazy"></p><p><strong>图 4 选择水印文件</strong></p><p>两项都选择完毕后提示选择完成，</p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfschv.png#height=142&amp;id=Wj0Ce&amp;originHeight=142&amp;originWidth=371&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=371" alt="" loading="lazy"></p><p><strong>图 5 选择完毕 帮助提示框</strong></p><p>对于取消选择未设置警告与报错提示，防止过多弹窗</p><p><strong>2 载体图像小波变换</strong></p><p>这部分未单独新开按钮和图片显示窗口，但程序的确执行了，用户无需知晓</p><p><strong>3 水印图像的预处理</strong></p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfs5JR.png#height=628&amp;id=aSeGm&amp;originHeight=628&amp;originWidth=702&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=702" alt="" loading="lazy"></p><p><strong>图 6 预处理成二值图像后的水印</strong></p><p><strong>4 小波数字水印的嵌入</strong></p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfsAjg.png#height=628&amp;id=wd2h4&amp;originHeight=628&amp;originWidth=702&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=702" alt="" loading="lazy"></p><p><strong>图 7 原始水印和置乱水印以及原始图像和添加水印之后的图像对比</strong></p><p><strong>5 小波数字水印的提取</strong></p><p><img src= "" data-lazy-src="https://t1.picb.cc/uploads/2020/06/09/tfs848.png#height=628&amp;id=gbbfW&amp;originHeight=628&amp;originWidth=702&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=702" alt="" loading="lazy"></p><p><strong>图 8 原始水印和提取的水印的对比</strong></p><p>将原始水印和提取水印进行对比，两个相关系数为 0.99356，相关系数越接近 1, 则提取的水印和原始水印越相似。</p></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/">CC康纳百川</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/posts/digital-watermark-detection-based-on-wavelet-transform/">https://blog.ccknbc.cc/posts/digital-watermark-detection-based-on-wavelet-transform/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><i style="color:#8fbc8f" class="fa-brands fa-creative-commons"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-by"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-nc"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-sa"></i> CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://blog.ccknbc.cc">CC的部落格</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E5%AD%A6%E4%B9%A0/">学习</a></div><div class="post_share"><div class="social-share" data-image="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/fea97888a40f0b051ab6f4b18057d37b_w2240_h1260_s3560.jpg" data-sites="wechat,weibo,qq,facebook,twitter"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload='this.media="all"'><script src="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i>赞赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://www.rocschool.com/tool/qr/qr/id/51.html" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/qr.png" alt="三合一"></a><div class="post-qr-code-desc">三合一</div></li><li class="reward-item"><a href="https://afdian.net/@ccknbc" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/afdian.png" alt="爱发电"></a><div class="post-qr-code-desc">爱发电</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="next-post pull-full"><a href="/posts/production-practice/" title="生产实习"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/5bcc1fd0cc7119c390ab4a548a8e795b_w2240_h1260_s2562.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">生产实习</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/research-on-image-denoising-technology-based-on-wavelet-transform/" title="基于小波变换的图像去噪技术研究"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/ebc53ed2b398f225bf5085a280c3056b_w1920_h1080_s682.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-01-10</div><div class="title">基于小波变换的图像去噪技术研究</div></div></a></div><div><a href="/posts/how-to-ask-questions-the-smart-way/" title="提问的智慧"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/992af8cade7b70420611f9c7d2165c1c_w1920_h1080_s263.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-30</div><div class="title">提问的智慧</div></div></a></div><div><a href="/posts/course-design/" title="课程设计"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/834fac4fc3bae7624af63e8e9aaf566e_w1920_h1080_s334.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-11-03</div><div class="title">课程设计</div></div></a></div><div><a href="/posts/production-practice/" title="生产实习"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/5bcc1fd0cc7119c390ab4a548a8e795b_w2240_h1260_s2562.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-06-29</div><div class="title">生产实习</div></div></a></div></div></div><hr class="custom-hr"><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="waline-wrap"></div></div></div></div></div></main><footer id="footer" style="background:linear-gradient(135deg,#fff1eb,#ace0f9)"><div id="footer-wrap"><div class="icp"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/icp.png" alt="ICP"><span>鄂 ICP 备 2020019764 号</span></a></div><div class="gongan"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.beian.gov.cn/portal/registerSystemInfo?recordcode=42088102000092"><img class="gongan-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/gongan.png" alt="gongan"><span>鄂公网安备 42088102000092 号</span></a></div><div class="live"><span>本站已运行</span><span id="display_live"></span><span class="moe-text">CCKNBC All Rights Reserved.</span><script>function blog_live(){window.setTimeout(blog_live,1e3);var e=new Date("2020-06-04T00:00:00"),o=new Date,l=o.getFullYear(),o=o.getTime()-e.getTime(),e=864e5,t=365*e,i=Math.floor(o/t),t=Math.floor(o%t/e),e=Math.floor(o%e/60/60/1e3),a=Math.floor(o%36e5/60/1e3),o=Math.floor(o%6e4/1e3);display_live.innerHTML=" "+i+" 年 "+t+" 天 "+e+" 小时 "+a+" 分 "+o+" 秒<br>&copy; 2020 - "+l+" "}blog_live()</script></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><a class="edit-yuque" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.yuque.com/ccknbc/blog/-1/edit/" title="在语雀上以富文本格式编辑/预览 - 基于小波变换的数字水印检测"><i class="fa-solid fa-crow"></i></a><button id="readmode" type="button" title="阅读模式"><i class="fa-solid fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fa-solid fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fa-solid fa-cog"></i></button><button id="share-link" type="button" title="分享链接"><i class="fa-solid fa-share"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fa-solid fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fa-solid fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.js"></script><script src="https://jsd.cdn.zzko.cn/npm/instant.page/instantpage.js" type="module"></script><script src="https://jsd.cdn.zzko.cn/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.js"></script><div class="js-pjax"><script>(()=>{var e=()=>{var e;const t=document.querySelectorAll("#article-container .mermaid-wrap");0!==t.length&&(e=()=>{{var e=t;window.loadMermaid=!0;const a="dark"===document.documentElement.getAttribute("data-theme")?"dark":"default";Array.from(e).forEach((e,t)=>{const n=e.firstElementChild;e="%%{init:{ 'theme':'"+a+"'}}%%\n"+n.textContent;const d=mermaid.render("mermaid-"+t,e);"string"==typeof d?(t=d,n.insertAdjacentHTML("afterend",t)):d.then(({svg:e})=>{n.insertAdjacentHTML("afterend",e)})})}},btf.addGlobalFn("themeChange",e,"mermaid"),window.loadMermaid?e():btf.getScript("https://jsd.cdn.zzko.cn/npm/mermaid/dist/mermaid.min.js").then(e))};btf.addGlobalFn("encrypt",e,"mermaid"),window.pjax?e():document.addEventListener("DOMContentLoaded",e)})()</script><script>(()=>{let n=window.walineFn||null;const t=e=>{const n=e(Object.assign({el:"#waline-wrap",serverURL:"https://waline.ccknbc.cc",pageview:!1,dark:'html[data-theme="dark"]',path:window.location.pathname,comment:!1,imageUploader:function(e){var n=new FormData,t=new Headers;return n.append("file",e),n.append("album_id","10"),n.append("permission","0"),t.append("Authorization","Bearer 24|o8Crl5y0oK3luyUs17fBxDtAcevk1iiLHVFMNjpA"),t.append("Accept","application/json"),fetch("https://wmimg.com/api/v1/upload",{method:"POST",headers:t,body:n}).then(e=>e.json()).then(e=>e.data.links.url)}},{pageSize:10,meta:["nick","mail","link"],requiredMeta:["nick","mail"],login:"force",copyright:!0,search:!0,turnstileKey:"0x4AAAAAAAECBl27OB5SZrQT",locale:{admin:"博主",sofa:"这里冷冷清清的，快来留下脚印吧！",placeholder:"根据《互联网跟帖评论服务管理规定》，将展示您的归属地，并开启强制注册登录后才允许评论\n社交登录现已支持【QQ Weibo GitHub X Facebook】等平台，登录后可点击头像更改个人主页地址，方便CC串门\n在评论框粘贴图片，自动上传至图床，请不要将评论区作为您的图床，更不要上传违法图片，谢谢合作",reactionTitle:"就现在，表明你的态度！",reaction0:"鼓励",reaction1:"菜狗",reaction2:"正确",reaction3:"错误",reaction4:"思考",reaction5:"无聊",level0:"买菜",level1:"切菜",level2:"炒菜",level3:"煲汤",level4:"煮面",level5:"上桌",level6:"开吃"},emoji:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/"],reaction:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/鼓掌.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/菜狗.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/正确.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/错误.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/思考.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/睡觉.png"]}));btf.addGlobalFn("pjax",()=>{n.destroy()},"destroyWaline")};var e=()=>{n?t(n):(btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.css"),btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline-meta.css").then(()=>import("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.js")).then(({init:e})=>{n=e||Waline.init,t(n),window.walineFn=n}))};btf.loadComment(document.getElementById("waline-wrap"),e)})()</script></div><script>window.addEventListener("load",()=>{const t=e=>e=""!==e&&150<(e=(e=(e=(e=e.replace(/<img.*?src="(.*?)"?[^\>]+>/gi,"[图片]")).replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi,"[链接]")).replace(/<pre><code>.*?<\/pre>/gi,"[代码]")).replace(/<[^>]+>/g,"")).length?e.substring(0,150)+"...":e,a=t=>{let a="";if(t.length)for(let e=0;e<t.length;e++)a=(a+="<div class='aside-list-item'>")+`<div class='content'>
        <a class='comment' href='${t[e].url}' title='${t[e].content}'>${t[e].content}</a>
        <div class='name'><span>${t[e].nick} / </span><time datetime="${t[e].date}">${btf.diffDate(t[e].date,!0)}</time></div>
        </div></div>`;else a+="没有评论";var e=document.querySelector("#card-newest-comments .aside-list");e&&(e.innerHTML=a),window.lazyLoadInstance&&window.lazyLoadInstance.update(),window.pjax&&window.pjax.refresh(e)};var e=()=>{var e;document.querySelector("#card-newest-comments .aside-list")&&((e=btf.saveToLocal.get("waline-newest-comments"))?a(JSON.parse(e)):(async()=>{try{var e=(await(await fetch("https://waline.ccknbc.cc/api/comment?type=recent&count=3",{method:"GET"})).json()).data.map(e=>({content:t(e.comment),avatar:e.avatar,nick:e.nick,url:e.url+"#post-comment",date:e.time||e.insertedAt}));btf.saveToLocal.set("waline-newest-comments",JSON.stringify(e),10/1440),a(e)}catch(e){console.error(e),document.querySelector("#card-newest-comments .aside-list").textContent="无法获取评论，请确认相关配置是否正确"}})())};e(),btf.addGlobalFn("pjaxComplete",e,"waline_newestComment")})</script><script defer src="/js/custom.js"></script><script src="https://jsd.cdn.zzko.cn/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors=["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"];var pjax=new Pjax({elements:'a:not([target="_blank"])',selectors:pjaxSelectors,cacheBust:!1,analytics:!1,scrollRestoration:!1});const triggerPjaxFn=e=>{e&&Object.values(e).forEach(e=>{e()})};document.addEventListener("pjax:send",function(){btf.removeGlobalFnEvent("pjax"),btf.removeGlobalFnEvent("themeChange");var e=document.body.classList;e.contains("read-mode")&&e.remove("read-mode"),triggerPjaxFn(window.globalFn.pjaxSend)}),document.addEventListener("pjax:complete",()=>{document.querySelectorAll("script[data-pjax]").forEach(e=>{const t=document.createElement("script");var a=e.text||e.textContent||e.innerHTML||"";Array.from(e.attributes).forEach(e=>t.setAttribute(e.name,e.value)),t.appendChild(document.createTextNode(a)),e.parentNode.replaceChild(t,e)}),triggerPjaxFn(window.globalFn.pjaxComplete)}),document.addEventListener("pjax:error",e=>{404===e.request.status&&pjax.loadUrl("/404")})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div class="docsearch-wrap"><div id="docsearch" style="display:none"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@docsearch/css/dist/style.css"><script src="https://jsd.cdn.zzko.cn/npm/@docsearch/js/dist/umd/index.js"></script><script>(()=>{docsearch(Object.assign({appId:"97MUPN4DMC",apiKey:"a003a39f337f5186ec11f5f92bae62b3",indexName:"ccknbc",container:"#docsearch"},{placeholder:"Ctrl/⌘ + K 唤醒搜索服务",maxResultsPerGroup:7,translations:{button:{buttonText:"搜索",buttonAriaLabel:"搜索"},modal:{searchBox:{resetButtonTitle:"清空",resetButtonAriaLabel:"清空",cancelButtonText:"取消",cancelButtonAriaLabel:"取消"},startScreen:{recentSearchesTitle:"最近搜索历史",noRecentSearchesText:"搜索历史为空",saveRecentSearchButtonTitle:"保存搜索记录",removeRecentSearchButtonTitle:"清除搜索记录",favoriteSearchesTitle:"收藏夹",removeFavoriteSearchButtonTitle:"移出收藏夹"},errorScreen:{titleText:"未能获取搜索结果",helpText:"您可能需要检查您的网络连接"},footer:{selectText:"选择",selectKeyAriaLabel:"回车键",navigateText:"切换",navigateUpKeyAriaLabel:"方向键上",navigateDownKeyAriaLabel:"方向键下",closeText:"关闭",closeKeyAriaLabel:"退出键",searchByText:"搜索服务提供: DocSearch by"},noResultsScreen:{noResultsText:"未搜索到相关内容",suggestedQueryText:"您可尝试搜索",reportMissingResultsText:"确认搜索结果是正确的？",reportMissingResultsLinkText:"反馈给Algolia"}}}}));const e=()=>{document.querySelector(".DocSearch-Button").click()};var t=()=>{btf.addEventListenerPjax(document.querySelector("#search-button > .search"),"click",e)};t(),window.addEventListener("pjax:complete",t)})()</script></div></div><script>const copyright_enable=!0</script><script src="https://jsd.cdn.zzko.cn/npm/turndown/dist/turndown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/copyMarkdown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/reprint.min.js"></script><script>(function (w, d, s, id) {
        if (typeof (w.webpushr) !== 'undefined') return;
        w.webpushr = w.webpushr || function () { (w.webpushr.q = w.webpushr.q || []).push(arguments) };
        var js, fjs = d.getElementsByTagName(s)[0];
        js = d.createElement(s);
        js.id = id;
        js.async = 1;
        js.src = "https://cdn.webpushr.com/app.min.js";
        fjs.parentNode.appendChild(js);
        }(window, document, 'script', 'webpushr-jssdk'));

        webpushr('setup', {
        'key': 'BB9Y-w9p3u0CKA7UP9nupB6I-_NqE2MuODmKJjyC4W2YflX06Ff_hEhrNJfonrut5l6gCa28gC83q2OII7Qv-oA',
        'sw': 'none'
        });
        </script></body></html>